Skip to content

fix(docker-ecr): keep prerelease suffix in the published image tag - #91

Merged
null-paorodrigues merged 1 commit into
mainfrom
fix/preserve-prerelease-in-image-tag
Aug 25, 2026
Merged

fix(docker-ecr): keep prerelease suffix in the published image tag#91
null-paorodrigues merged 1 commit into
mainfrom
fix/preserve-prerelease-in-image-tag

Conversation

@null-paorodrigues

Copy link
Copy Markdown
Contributor

What

The published tag was derived with an unanchored extraction:

VERSION=$(echo "${TAG}" | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' || echo "${TAG}")

The intent is prefix stripping (logs-controller-v2.0.0 -> v2.0.0), but as an
unanchored grep -oE it also matches the substring v1.2.3 inside v1.2.3-beta and
drops the prerelease suffix, so the image is pushed as :v1.2.3.

Two consequences:

  1. A prerelease publishes under the release tag. v1.2.3-beta lands on :v1.2.3,
    and whichever of the two builds runs last wins. Any digest recorded downstream then
    points at prerelease content under a release version.
  2. Anything resolving the pushed image by tag breaks. An overlay image doing
    FROM <base>:${BASE_VERSION}, with BASE_VERSION taken from github.ref_name, gets
    manifest unknown — the base landed under a tag the caller never sees.

The || echo "${TAG}" fallback is why this stayed latent: tags with no vX.Y.Z
substring (beta, latest, 1.2.3) never matched and passed through untouched. Only a
v-prefixed prerelease triggers it.

Change

Anchored match separating an optional prefix from the full SemVer, so prerelease and
build metadata survive:

if [[ "${TAG}" =~ ^(.*-)?(v?[0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.-]+)?)$ ]]; then
  VERSION="${BASH_REMATCH[2]}"
else
  VERSION="${TAG}"
fi

Plus a new image_tag output exposing the resolved tag, so a caller that needs to
reference the pushed image can read it instead of re-deriving it from github.ref_name.
That re-derivation is exactly the assumption that breaks in consequence 2 above — a
reusable workflow that normalises an input should hand the result back rather than leave
callers coupled to an internal detail.

Verified

Ran the old and the new logic side by side over the tag shapes this workflow receives
today:

tag input expected before after
v1.2.3-beta v1.2.3-beta v1.2.3
v1.2.3-beta.1 v1.2.3-beta.1 v1.2.3
v1.2.3+build.5 v1.2.3+build.5 v1.2.3
v1.2.3 v1.2.3
1.2.3 1.2.3
beta beta
latest latest
logs-controller-v2.0.0 v2.0.0
some-image-1.8.0 1.8.0 ❌ passed through whole

No behaviour change for any tag shape in use other than the prerelease cases. The last
row is a bonus fix: an unprefixed monorepo-style tag used to pass through whole, because
it has no v for the old pattern to match.

actionlint reports no findings on the file.

Not included

No regression test — there is no harness in this repo for the shell embedded in run:
blocks. The comparison above was run by hand.

The version was extracted with an unanchored `grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+'`.
Because `v1.2.3-beta` contains `v1.2.3` as a substring, the match dropped the
suffix and the image was pushed as `:v1.2.3` — a prerelease squatting the
release tag, with the digest registered against the wrong version.

Replace the extraction with an anchored match that separates an optional
monorepo prefix from the full SemVer, so prerelease and build metadata survive.
Tags that aren't semver-shaped (`beta`, `latest`) still pass through untouched,
and `logs-controller-v2.0.0 -> v2.0.0` keeps working.

Also expose the resolved tag as a new `image_tag` output. Callers that need to
reference the pushed image (e.g. an overlay image doing `FROM <base>:<tag>`)
were passing `github.ref_name` and assuming the reusable does not transform it,
which is exactly the assumption that broke here.

Verified against the real tag inputs of every caller of this workflow: no
change in behaviour for any of them other than the prerelease case.
@null-paorodrigues
null-paorodrigues merged commit 0520a07 into main Aug 25, 2026
2 checks passed
@null-paorodrigues
null-paorodrigues deleted the fix/preserve-prerelease-in-image-tag branch August 25, 2026 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants